package com.inspur.security.cbb3.kms.keyusage.dataorders.service.impl;

import com.inspur.security.cbb3.kms.config.rabbitmq.RabbitConstant;
import com.inspur.security.cbb3.kms.enums.*;
import com.inspur.security.cbb3.kms.exception.UserInfoInVaildException;
import com.inspur.security.cbb3.kms.keymanager.secrets.po.SecretsBean;
import com.inspur.security.cbb3.kms.keymanager.secrets.repository.SecretsRepository;
import com.inspur.security.cbb3.kms.keymanager.secrets.service.SecretsService;
import com.inspur.security.cbb3.kms.keymanager.secrets.vo.KeyContentVO;
import com.inspur.security.cbb3.kms.keyusage.data.po.DataBean;
import com.inspur.security.cbb3.kms.keyusage.data.repository.DataRepository;
import com.inspur.security.cbb3.kms.keyusage.dataorders.po.DataOrdersBean;
import com.inspur.security.cbb3.kms.keyusage.dataorders.repository.DataOrdersRepository;
import com.inspur.security.cbb3.kms.keyusage.dataorders.service.DataOrdersService;
import com.inspur.security.cbb3.kms.keyusage.dataorders.vo.DataOrdersAddVO;
import com.inspur.security.cbb3.kms.rabbitmq.sender.SignWebSender;
import com.inspur.security.cbb3.kms.sysuser.po.SysUserBean;
import com.inspur.security.cbb3.kms.sysuser.service.SysUserService;
import com.inspur.security.cbb3.kms.utils.DateUtil;
import com.inspur.security.cbb3.kms.utils.KeyUtil;
import com.inspur.security.cbb3.kms.utils.PageRequestDate;
import com.inspur.security.cbb3.kms.utils.RegExpUtil;
import com.inspur.security.cbb3.kms.utils.parameter.cipher.impl.*;
import com.inspur.security.cbb3.kms.utils.parameter.messagedigest.impl.MessageDigestParamsImpl;
import com.inspur.security.cbb3.kms.utils.parameter.signature.impl.DSASignatureParams;
import com.inspur.security.cbb3.kms.utils.parameter.signature.impl.RSASignatureParams;
import com.inspur.security.cbb3.kms.utils.parameter.signature.impl.SM2SignatureParams;
import javassist.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.procedure.ParameterMisuseException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.MissingServletRequestParameterException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.persistence.criteria.Predicate;
import javax.validation.ValidationException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.text.ParseException;
import java.util.*;

/**
 * DataOrdersServiceImpl
 *
 * @author liukai
 * @date 2020/10/15
 **/
@Slf4j
@Service
@Transactional(readOnly = true)
public class DataOrdersServiceImpl implements DataOrdersService {

    @Autowired
    private DataOrdersRepository dataOrdersRepository;

    @Autowired
    private DataRepository dataRepository;

    @Autowired
    private SecretsRepository secretsRepository;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SignWebSender signWebSender;

    @Autowired
    private SecretsService secretsService;

    @Value("${signweb.need.rabbitmq}")
    private boolean needRabbitMq=false;

    @Value("${signweb.data.deleteCycle}")
    private String deleteCycle="3";

    @Value("${signweb.data.length}")
    private String dataAlowLength="1024000";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataOrdersBean addDataOrder(DataOrdersBean dataOrdersBean, DataBean dataBean) {
        //参数校验，单独校验和关联校验
        //单独校验
        SysUserBean loginUser = sysUserService.findLoginSysUser();
        if (loginUser == null) {
            throw new UserInfoInVaildException();
        }
        if (!RegExpUtil.checkDataAction(dataOrdersBean.getAction())){
            throw new ValidationException("数据操作类型不支持");
        }
        if (!RegExpUtil.checkAlgorithm(dataOrdersBean.getAlgorithm())){
            throw new ValidationException("算法不支持");
        }
        if (!RegExpUtil.checkData(dataBean.getData(),Integer.parseInt(dataAlowLength))){
            throw new ValidationException("数据为空或过长");
        }
        if (!RegExpUtil.checkDataContentEncoding(dataBean.getDataContentEncoding())){
            throw new ValidationException("数据编码格式不支持");
        }

        if (!RegExpUtil.checkDataOutputEncoding(dataOrdersBean.getOutputEncoding())){
            throw new ValidationException("密文输出格式不支持");
        }
        //关联校验
        if(!RegExpUtil.checkDataActionAndAlgorithm(dataOrdersBean.getAction(),dataOrdersBean.getAlgorithm())){
            throw new ValidationException("数据操作类型算法不匹配");
        }
        //若是计算hash，则keyoutside和keyid可以为空
        if (!DataActionType.hash.name().equalsIgnoreCase(dataOrdersBean.getAction())){
            if (StringUtils.isEmpty(dataOrdersBean.getKeyOutside())&& StringUtils.isEmpty(dataOrdersBean.getKeyId())){
                throw new ValidationException("缺少密钥信息");
            }
            if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())&& StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                throw new ValidationException("外部密钥和内部密钥只能选择一个");
            }
        }
        //校验key_id是否存在,是否有权限
        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
            try {
                SecretsBean secretsBean = checkKeyPermission(dataOrdersBean.getKeyId());
                if (secretsBean.getDeleted()){
                    throw new ValidationException("密钥不存在");
                }
            } catch (Exception e) {
                throw new ValidationException("密钥不存在");
            }
            //校验keyId与算法是否匹配
            if (!checkKeyIdAlgorithm(dataOrdersBean.getKeyId(),dataOrdersBean.getAlgorithm())){
                throw new ValidationException("算法与密钥不匹配");
            }
        }

        //对称加密参数校验
        if (RegExpUtil.isSymmetricAlgorithm(dataOrdersBean.getAlgorithm())){
            if (!RegExpUtil.checkEncryptMode(dataOrdersBean.getEncryptMode())){
                throw new ValidationException("数据加密模式为空或不支持");
            }
            if (!RegExpUtil.checkPaddingMode(dataOrdersBean.getPaddingMode())){
                throw new ValidationException("加密填充模式为空或不支持");
            }
            if (EncryptMode.CBC.name().equalsIgnoreCase(dataOrdersBean.getEncryptMode()) && !RegExpUtil.checkIv(dataOrdersBean.getAlgorithm(),dataOrdersBean.getIv())){
                throw new ValidationException("偏移量格式或长度不规范");
            }
            if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside()) && !RegExpUtil.isStrMatchEncoding(dataOrdersBean.getAlgorithm(),dataOrdersBean.getKeyOutside(),dataOrdersBean.getKeyContentEncoding())){
                throw new ValidationException("密钥内容与输入格式不匹配");
            }
        }else if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
            //非对称参数校验
            //操作与外部密钥格式是否匹配
            String keyFormat = KeyUtil.getKeyFormat(dataOrdersBean.getKeyOutside());
            if (StringUtils.isEmpty(keyFormat)){
                throw new ValidationException("密钥格式不支持");
            }
            dataOrdersBean.setKeyContentEncoding(keyFormat);
            //校验外部密钥是否包含密码
            if (KeyUtil.isEncryptedPemKey(dataOrdersBean.getKeyOutside())){
                if (StringUtils.isEmpty(dataOrdersBean.getKeyPassword())){
                    throw new ValidationException("该密钥需要输入密码");
                }
            }

        }
        //若是计算签名，校验摘要算法
        if (DataActionType.sign.name().equalsIgnoreCase(dataOrdersBean.getAction()) || DataActionType.verify.name().equalsIgnoreCase(dataOrdersBean.getAction())){
            if (!RegExpUtil.checkSignHash(dataOrdersBean.getAlgorithm(),dataOrdersBean.getHashAlgorithm())){
                throw new ValidationException("签名算法与hash摘要算法不匹配");
            }
        }
        //根据操作类型和算法不同校验数据长度
        switch (DataActionType.getByType(dataOrdersBean.getAction())){
            case encrypt:
                if (RegExpUtil.isSymmetricAlgorithm(dataOrdersBean.getAlgorithm()) || AlgorithmType.sm2.name().equalsIgnoreCase(dataOrdersBean.getAlgorithm())){
                    //对称加密和sm2加密数据长度可配置
                    if (!RegExpUtil.checkData(dataBean.getData(),Integer.parseInt(dataAlowLength))){
                        throw new ValidationException("数据为空或过长");
                    }
                }else {
                    //rsa加密数据长度117byte(1024)、245byte(2048)、501byte(4096),没法校验密钥长度，所以只能取最小长度117byte
                    if (!RegExpUtil.checkRsaData(dataBean.getData())){
                        throw new ValidationException("数据为空或过长");
                    }
                }
            case sign:
            case hash:
                if (!RegExpUtil.checkData(dataBean.getData(),Integer.parseInt(dataAlowLength))){
                    throw new ValidationException("数据为空或过长");
                }
            default:
        }

        //数据存储
        try {
            dataBean.setCreatorId(loginUser.getUuid());
            dataBean.setCreatedTime(DateUtil.getNowDate());
            DataBean saveDataBean = dataRepository.save(dataBean);
            //数据订单存储
            dataOrdersBean.setDataId(saveDataBean.getUuid());
            dataOrdersBean.setCreatedTime(saveDataBean.getCreatedTime());
            dataOrdersBean.setCreatorId(loginUser.getUuid());
            dataOrdersBean.setStatus(KeyOrderStatus.Pending.name());
            dataOrdersRepository.save(dataOrdersBean);
            log.info("addDataOrder,uuid: "+dataOrdersBean.getUuid());
        }catch (Exception e){
            throw new RequestRejectedException("订单生成失败");
        }
        return dataOrdersBean;
    }

    @Override
    public void sendOrder(String uuid){
        //配置文件读取异步参数，判断异步还是同步
        if(needRabbitMq){
            Map<String,String> message=new HashMap(3);
            message.put("method", RabbitConstant.METHOD_DATAORDER_ADD);
            message.put("uuid",uuid);
            message.put("time", DateUtil.getNowDate());
            signWebSender.send(message);
        }else{
            //直接进行计算
            mqHandleOrder(uuid);
        }
    }

    @Override
    public Page<DataOrdersBean> searchDataOrders(PageRequestDate pageRequestDate, DataOrdersAddVO searchParams) {
        //参数校验
        if(!RegExpUtil.checkTimeFormat(searchParams.getBeginTimeBegin())||!RegExpUtil.checkTimeFormat(searchParams.getBeginTimeEnd())){
            log.info("time format error ");
            throw new ValidationException("查询时间格式错误。");
        }
        if (StringUtils.isNotEmpty(searchParams.getAction())&&!RegExpUtil.checkDataAction(searchParams.getAction())){
            log.info("action type not support ");
            throw new ValidationException("计算类型输入错误。");
        }
        if (StringUtils.isNotEmpty(searchParams.getStatus())){
            if (KeyOrderStatus.getByType(searchParams.getStatus())==KeyOrderStatus.OTHER){
                log.info("status type not support ");
                throw new ValidationException("订单状态输入错误。");
            }
        }
        //当前登录用户
        SysUserBean loginUser = sysUserService.findLoginSysUser();
        if (loginUser == null) {
            throw new UserInfoInVaildException();
        }
        //分页查找
        return dataOrdersRepository.findAll((Specification<DataOrdersBean>) (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            if(StringUtils.isNotEmpty(searchParams.getAction())){
                list.add(cb.equal(root.get("action").as(String.class), DataActionType.getByType(searchParams.getAction()).name()));
            }
            if(StringUtils.isNotEmpty(searchParams.getStatus())){
                list.add(cb.equal(root.get("status").as(String.class), KeyOrderStatus.getByType(searchParams.getStatus()).name()));
            }
            if(StringUtils.isNotEmpty(searchParams.getBeginTimeBegin())){
                list.add(cb.greaterThanOrEqualTo(root.get("createdTime").as(String.class), searchParams.getBeginTimeBegin()));
            }
            if(StringUtils.isNotEmpty(searchParams.getBeginTimeEnd())){
                list.add(cb.lessThanOrEqualTo(root.get("createdTime").as(String.class), searchParams.getBeginTimeEnd()));
            }
            list.add(cb.equal(root.get("creatorId").as(String.class), loginUser.getUuid()));
            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        }, pageRequestDate.getPageRequest());
    }

    @Override
    public DataOrdersBean searchDataOrder(String uuid) throws NotFoundException, MissingServletRequestParameterException {
        //参数校验
        return checkPermission(uuid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDataOrder(String uuid) throws MissingServletRequestParameterException, NotFoundException {
        //参数校验
        if (StringUtils.isEmpty(uuid)){
            throw new MissingServletRequestParameterException("主键字段uuid", "String");
        }
        //权限校验
        DataOrdersBean dataOrderBean = checkPermission(uuid);
        //根据order_uuid删除数据订单
        dataOrdersRepository.deleteById(uuid);
        //根据data_uuid删除数据
        dataRepository.deleteById(dataOrderBean.getDataId());
    }

    @Override
    public void mqHandleOrder(String uuid) {
        //查询订单
        Optional<DataOrdersBean> dataOrdersBeanOptional = dataOrdersRepository.findById(uuid);
        if (!dataOrdersBeanOptional.isPresent()){
            log.info("dataOrder dose not exist,uuid: "+uuid);
            return;
        }
        DataOrdersBean dataOrdersBean = dataOrdersBeanOptional.get();
        //从数据表中获取带计算数据
        Optional<DataBean> dataBeanOptional = dataRepository.findById(dataOrdersBean.getDataId());
        if (!dataBeanOptional.isPresent()){
            log.info("data dose not exist");
            return;
        }
        DataBean dataBean = dataBeanOptional.get();
        //根据action类型判断是hash、encrypt、decrypt、sign、verify
        String keyContent = getKeyContent(dataOrdersBean);
        String keyPassword = getKeyPassword(dataOrdersBean);
        switch (DataActionType.getByType(dataOrdersBean.getAction())){
            case hash:
//                //根据算法类型计算hash
                MessageDigestParamsImpl params=new MessageDigestParamsImpl();
                params.setPlaintext(dataBean.getData());
                params.setCharset(dataBean.getDataContentEncoding());
                params.setAlgorithm("SM3");
                try {
                    //计算hash, 将计算结果保存到数据库
                    KeyUtil.hash(params);
                    if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                        dataRepository.updataResultData(params.getHashValueHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                    }else {
                        //默认输出base64格式
                        dataRepository.updataResultData(params.getHashValueBase64(),DataOutputType.Base64.name(),dataBean.getUuid());
                    }
                    //更新订单状态为success
                    dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                    return;
                } catch (Exception e) {
                    //将报错原因记录到订单中，并将订单状态改为Failed
                    log.error("hash error: "+e.toString());
                    dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                    dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                    return;
                }
            case encrypt:
                //根据算法类型、密钥进行加密计算
                switch (AlgorithmType.getByType(dataOrdersBean.getAlgorithm())){
                    case aes:
                        AESCipherParams aesCipherParams = new AESCipherParams();
                        aesCipherParams.setPlaintext(dataBean.getData());
                        aesCipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                aesCipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                aesCipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    aesCipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    aesCipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        aesCipherParams.setMode(dataOrdersBean.getEncryptMode());
                        aesCipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        if (StringUtils.isNotEmpty(dataOrdersBean.getIv())){
		                    aesCipherParams.setIV(dataOrdersBean.getIv());
                        }
                        try {
                            KeyUtil.encrypt(aesCipherParams);
                            //保存密文
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(aesCipherParams.getCiphertextHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                //默认输出base64格式
                                dataRepository.updataResultData(aesCipherParams.getCiphertextBase64(),DataOutputType.Base64.name(),dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("aes encrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm4:
                        SM4CipherParams sm4CipherParams = new SM4CipherParams();
                        sm4CipherParams.setPlaintext(dataBean.getData());
                        sm4CipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm4CipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm4CipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    sm4CipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    sm4CipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        sm4CipherParams.setMode(dataOrdersBean.getEncryptMode());
                        sm4CipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        if (StringUtils.isNotEmpty(dataOrdersBean.getIv())){
                            sm4CipherParams.setIV(dataOrdersBean.getIv());
                        }
                        try {
                            KeyUtil.encrypt(sm4CipherParams);
                            //保存密文
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(sm4CipherParams.getCiphertextHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(sm4CipherParams.getCiphertextBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm4 encrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case desede:
                        DES3CipherParams des3CipherParams = new DES3CipherParams();
                        des3CipherParams.setPlaintext(dataBean.getData());
                        des3CipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                des3CipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                des3CipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    des3CipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    des3CipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        des3CipherParams.setMode(dataOrdersBean.getEncryptMode());
                        des3CipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        if (StringUtils.isNotEmpty(dataOrdersBean.getIv())){
                            des3CipherParams.setIV(dataOrdersBean.getIv());
                        }
                        try {
                            KeyUtil.encrypt(des3CipherParams);
                            //保存密文
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(des3CipherParams.getCiphertextHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(des3CipherParams.getCiphertextBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("desede encrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case rsa:
                        RSACipherParams rsaCipherParams = new RSACipherParams();
                        rsaCipherParams.setPlaintext(dataBean.getData());
                        rsaCipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricPublicKeyFormatType.X509.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                rsaCipherParams.setPubKeyX509Pem(keyContent);
                            }else {
                                rsaCipherParams.setPubKeyPKCS1Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricPublicKeyFormatType.X509.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaCipherParams.setPubKeyX509Pem(keyContent);
                                }else if (AsymmetricPublicKeyFormatType.Pkcs1.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaCipherParams.setPubKeyPKCS1Pem(keyContent);
                                }
                            }
                        }

                        try {
                            KeyUtil.encrypt(rsaCipherParams);
                            //保存密文
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(rsaCipherParams.getCiphertextHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(rsaCipherParams.getCiphertextBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("rsa encrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm2:
                        SM2CipherParams sm2CipherParams = new SM2CipherParams();
                        sm2CipherParams.setPlaintext(dataBean.getData());
                        sm2CipherParams.setCharset(dataBean.getDataContentEncoding());
                        sm2CipherParams.setPubKeyX509Pem(keyContent);
                        try {
                            KeyUtil.encrypt(sm2CipherParams);
                            //保存密文
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(sm2CipherParams.getCiphertextHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(sm2CipherParams.getCiphertextBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm2 encrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    default:
                        //算法不支持
                        log.error("algorithm not support: "+ dataOrdersBean.getAlgorithm());
                        dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                        dataOrdersRepository.updataErrorReason("algorithm not support: "+ dataOrdersBean.getAlgorithm(),uuid);
                        return;

                }
            case decrypt:
                //根据算法类型、密钥进行解密计算
                switch (AlgorithmType.getByType(dataOrdersBean.getAlgorithm())){
                    case aes:
                        AESCipherParams aesCipherParams = new AESCipherParams();
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            aesCipherParams.setCiphertextHex(dataBean.getData());
                        }else {
                            aesCipherParams.setCiphertextBase64(dataBean.getData());
                        }
                        aesCipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                aesCipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                aesCipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    aesCipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    aesCipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        aesCipherParams.setMode(dataOrdersBean.getEncryptMode());
                        aesCipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        aesCipherParams.setIV(dataOrdersBean.getIv());
                        try {
                            KeyUtil.decrypt(aesCipherParams);
                            //保存解密明文
                            dataRepository.updataResultData(aesCipherParams.getPlaintext(),dataBean.getDataContentEncoding(),dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("aes decrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case desede:
                        DES3CipherParams des3CipherParams = new DES3CipherParams();
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            des3CipherParams.setCiphertextHex(dataBean.getData());
                        }else {
                            des3CipherParams.setCiphertextBase64(dataBean.getData());
                        }
                        des3CipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                des3CipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                des3CipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    des3CipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    des3CipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        des3CipherParams.setMode(dataOrdersBean.getEncryptMode());
                        des3CipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        if (StringUtils.isNotEmpty(dataOrdersBean.getIv())){
                            des3CipherParams.setIV(dataOrdersBean.getIv());
                        }
                        try {
                            KeyUtil.decrypt(des3CipherParams);
                            dataRepository.updataResultData(des3CipherParams.getPlaintext(), dataBean.getDataContentEncoding(), dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("desede decrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm4:
                        SM4CipherParams sm4CipherParams = new SM4CipherParams();
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            sm4CipherParams.setCiphertextHex(dataBean.getData());
                        }else {
                            sm4CipherParams.setCiphertextBase64(dataBean.getData());
                        }
                        sm4CipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm4CipherParams.setKeyBase64(keyContent);
                            }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm4CipherParams.setKeyHex(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (SymmetricKeyFormatType.Base64.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    sm4CipherParams.setKeyBase64(keyContent);
                                }else if (SymmetricKeyFormatType.Hex.name().equalsIgnoreCase(secretsBean.getOutputFormat())){
                                    sm4CipherParams.setKeyHex(keyContent);
                                }
                            }
                        }
                        sm4CipherParams.setMode(dataOrdersBean.getEncryptMode());
                        sm4CipherParams.setPadding(dataOrdersBean.getPaddingMode());
                        if (StringUtils.isNotEmpty(dataOrdersBean.getIv())){
                            sm4CipherParams.setIV(dataOrdersBean.getIv());
                        }
                        try {
                            KeyUtil.decrypt(sm4CipherParams);
                            //保存解密后明文
                            dataRepository.updataResultData(sm4CipherParams.getPlaintext(), dataBean.getDataContentEncoding(), dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm4 decrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case rsa:
                        RSACipherParams rsaCipherParams = new RSACipherParams();
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            rsaCipherParams.setCiphertextHex(dataBean.getData());
                        }else {
                            rsaCipherParams.setCiphertextBase64(dataBean.getData());
                        }
                        rsaCipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                rsaCipherParams.setPriKeyPKCS1Pem(keyContent);
                            }else {
                                rsaCipherParams.setPriKeyPKCS8Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaCipherParams.setPriKeyPKCS1Pem(keyContent);
                                }else if (AsymmetricCommonPrivateKeyFormatType.Pkcs8.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaCipherParams.setPriKeyPKCS8Pem(keyContent);
                                }
                            }
                        }
                        rsaCipherParams.setPassword(keyPassword);
                        try {
                            KeyUtil.decrypt(rsaCipherParams);
                            //保存解密明文
                            dataRepository.updataResultData(rsaCipherParams.getPlaintext(), dataBean.getDataContentEncoding(), dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("rsa decrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm2:
                        SM2CipherParams sm2CipherParams = new SM2CipherParams();
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            sm2CipherParams.setCiphertextHex(dataBean.getData());
                        }else {
                            sm2CipherParams.setCiphertextBase64(dataBean.getData());
                        }
                        sm2CipherParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricSM2PrivateKeyFormatType.GMT.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm2CipherParams.setPriKeyGMTPem(keyContent);
                            }else {
                                sm2CipherParams.setPriKeyPKCS8Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricSM2PrivateKeyFormatType.GMT.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    sm2CipherParams.setPriKeyGMTPem(keyContent);
                                }else if (AsymmetricSM2PrivateKeyFormatType.Pkcs8.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    sm2CipherParams.setPriKeyPKCS8Pem(keyContent);
                                }
                            }
                        }
                        sm2CipherParams.setPassword(keyPassword);
                        try {
                            KeyUtil.decrypt(sm2CipherParams);
                            //保存解密后明文
                            dataRepository.updataResultData(sm2CipherParams.getPlaintext(), dataBean.getDataContentEncoding(), dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm2 decrypt error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    default:
                        //算法不支持
                        log.error("algorithm not support: "+ dataOrdersBean.getAlgorithm());
                        dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                        dataOrdersRepository.updataErrorReason("algorithm not support: "+ dataOrdersBean.getAlgorithm(),uuid);
                        return;
                }
            case sign:
                //根据算法类型、密钥进行签名计算
                switch (AlgorithmType.getByType(dataOrdersBean.getAlgorithm())) {
                    case rsa:
                        RSASignatureParams rsaSignatureParams = new RSASignatureParams();
                        rsaSignatureParams.setPlaintext(dataBean.getData());
                        rsaSignatureParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                rsaSignatureParams.setPriKeyPKCS1Pem(keyContent);
                            }else {
                                rsaSignatureParams.setPriKeyPKCS8Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaSignatureParams.setPriKeyPKCS1Pem(keyContent);
                                }else if (AsymmetricCommonPrivateKeyFormatType.Pkcs8.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaSignatureParams.setPriKeyPKCS8Pem(keyContent);
                                }
                            }
                        }
                        rsaSignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        rsaSignatureParams.setPassword(keyPassword);
                        try {
                            KeyUtil.sign(rsaSignatureParams);
                            //保存签名
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(rsaSignatureParams.getSignatureHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(rsaSignatureParams.getSignatureBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("rsa sign error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm2:
                        SM2SignatureParams sm2SignatureParams = new SM2SignatureParams();
                        sm2SignatureParams.setPlaintext(dataBean.getData());
                        sm2SignatureParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricSM2PrivateKeyFormatType.GMT.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                sm2SignatureParams.setPriKeyGMTPem(keyContent);
                            }else {
                                sm2SignatureParams.setPriKeyPKCS8Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricSM2PrivateKeyFormatType.GMT.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    sm2SignatureParams.setPriKeyGMTPem(keyContent);
                                }else if (AsymmetricSM2PrivateKeyFormatType.Pkcs8.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    sm2SignatureParams.setPriKeyPKCS8Pem(keyContent);
                                }
                            }
                        }
                        sm2SignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        sm2SignatureParams.setPassword(keyPassword);
                        try {
                            KeyUtil.sign(sm2SignatureParams);
                            //保存签名
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(sm2SignatureParams.getSignatureHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(sm2SignatureParams.getSignatureBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm2 sign error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case dsa:
                        DSASignatureParams dsaSignatureParams = new DSASignatureParams();
                        dsaSignatureParams.setPlaintext(dataBean.getData());
                        dsaSignatureParams.setCharset(dataBean.getDataContentEncoding());
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                dsaSignatureParams.setPriKeyPKCS1Pem(keyContent);
                            }else {
                                dsaSignatureParams.setPriKeyPKCS8Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricCommonPrivateKeyFormatType.Pkcs1.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    dsaSignatureParams.setPriKeyPKCS1Pem(keyContent);
                                }else if (AsymmetricCommonPrivateKeyFormatType.Pkcs8.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    dsaSignatureParams.setPriKeyPKCS8Pem(keyContent);
                                }
                            }
                        }
                        dsaSignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        dsaSignatureParams.setPassword(keyPassword);
                        try {
                            KeyUtil.sign(dsaSignatureParams);
                            //保存签名
                            if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                                dataRepository.updataResultData(dsaSignatureParams.getSignatureHex(),DataOutputType.Hex.name(),dataBean.getUuid());
                            }else {
                                dataRepository.updataResultData(dsaSignatureParams.getSignatureBase64(), DataOutputType.Base64.name(), dataBean.getUuid());
                            }
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("dsa sign error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    default:
                        //算法不支持
                        log.error("algorithm not support: "+ dataOrdersBean.getAlgorithm());
                        dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                        dataOrdersRepository.updataErrorReason("algorithm not support: "+ dataOrdersBean.getAlgorithm(),uuid);
                        return;

                }
            case verify:
                //根据算法类型、密钥进行验签计算
                switch (AlgorithmType.getByType(dataOrdersBean.getAlgorithm())) {
                    case rsa:
                        RSASignatureParams rsaSignatureParams = new RSASignatureParams();
                        rsaSignatureParams.setPlaintext(dataBean.getData());
                        rsaSignatureParams.setCharset(dataBean.getDataContentEncoding());
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            rsaSignatureParams.setSignatureHex(dataBean.getSignature());
                        }else {
                            rsaSignatureParams.setSignatureBase64(dataBean.getSignature());
                        }
                        //外部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
                            if (AsymmetricPublicKeyFormatType.Pkcs1.name().equalsIgnoreCase(dataOrdersBean.getKeyContentEncoding())){
                                rsaSignatureParams.setPubKeyPKCS1Pem(keyContent);
                            }else {
                                rsaSignatureParams.setPubKeyX509Pem(keyContent);
                            }
                        }
                        //内部密钥
                        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
                            //根据keyid查询到密钥属性信息
                            Optional<SecretsBean> secretsBeanOptional = secretsRepository.findById(dataOrdersBean.getKeyId());
                            if (secretsBeanOptional.isPresent()){
                                SecretsBean secretsBean = secretsBeanOptional.get();
                                if (AsymmetricPublicKeyFormatType.Pkcs1.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaSignatureParams.setPubKeyPKCS1Pem(keyContent);
                                }else if (AsymmetricPublicKeyFormatType.X509.name().equalsIgnoreCase(secretsBean.getKeyFormat())){
                                    rsaSignatureParams.setPubKeyX509Pem(keyContent);
                                }
                            }
                        }
                        rsaSignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        try {
                            KeyUtil.verify(rsaSignatureParams);
                            //保存验签结果
                            dataRepository.updataResultData(String.valueOf(rsaSignatureParams.getVerifyResult()),null,dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("rsa verify error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case dsa:
                        DSASignatureParams dsaSignatureParams = new DSASignatureParams();
                        dsaSignatureParams.setPlaintext(dataBean.getData());
                        dsaSignatureParams.setCharset(dataBean.getDataContentEncoding());
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            dsaSignatureParams.setSignatureHex(dataBean.getSignature());
                        }else {
                            dsaSignatureParams.setSignatureBase64(dataBean.getSignature());
                        }
                        //外部密钥
                        dsaSignatureParams.setPubKeyX509Pem(keyContent);
                        dsaSignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        try {
                            KeyUtil.verify(dsaSignatureParams);
                            //保存验签结果
                            dataRepository.updataResultData(String.valueOf(dsaSignatureParams.getVerifyResult()),null,dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("dsa verify error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    case sm2:
                        SM2SignatureParams sm2SignatureParams = new SM2SignatureParams();
                        sm2SignatureParams.setPlaintext(dataBean.getData());
                        sm2SignatureParams.setCharset(dataBean.getDataContentEncoding());
                        if (DataOutputType.Hex.name().equalsIgnoreCase(dataOrdersBean.getOutputEncoding())){
                            sm2SignatureParams.setSignatureHex(dataBean.getSignature());
                        }else {
                            sm2SignatureParams.setSignatureBase64(dataBean.getSignature());
                        }
                        //外部密钥
                        sm2SignatureParams.setPubKeyX509Pem(keyContent);
                        sm2SignatureParams.setAlgorithm(dataOrdersBean.getHashAlgorithm());
                        try {
                            KeyUtil.verify(sm2SignatureParams);
                            //保存验签结果
                            dataRepository.updataResultData(String.valueOf(sm2SignatureParams.getVerifyResult()),null,dataBean.getUuid());
                            //更新订单状态success
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Success.name(),uuid);
                            return;
                        } catch (Exception e) {
                            //将报错原因记录到订单中，并将订单状态改为Failed
                            log.error("sm2 verify error: "+e.toString());
                            dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                            dataOrdersRepository.updataErrorReason(e.getMessage(),uuid);
                            return;
                        }
                    default:
                        //算法不支持
                        log.error("algorithm not support: "+ dataOrdersBean.getAlgorithm());
                        dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                        dataOrdersRepository.updataErrorReason("algorithm not support: "+ dataOrdersBean.getAlgorithm(),uuid);
                        return;
                }
            default:
                //数据操作类型不支持
                log.error("action not support: "+ dataOrdersBean.getAction());
                dataOrdersRepository.updataStatus(KeyOrderStatus.Failed.name(),uuid);
                dataOrdersRepository.updataErrorReason("action not support: "+ dataOrdersBean.getAction(),uuid);
        }
    }

    /**
     * 获取计算所需密钥
     * @param dataOrdersBean 订单对象
     * @return 密钥明文
     */
    private String getKeyContent(DataOrdersBean dataOrdersBean){
        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
            return dataOrdersBean.getKeyOutside();
        }
        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
            //TODO 从密钥表中获取密钥
            KeyContentVO keyContentNoAuth = secretsService.getKeyContentNoAuth(dataOrdersBean.getKeyId());
            return keyContentNoAuth.getKeyContent();
        }
        return null;
    }

    /**
     * 获取非对称密钥密码
     * @param dataOrdersBean 订单对象
     * @return 密码明文
     */
    private String getKeyPassword(DataOrdersBean dataOrdersBean){
        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyOutside())){
            if (StringUtils.isNotEmpty(dataOrdersBean.getKeyPassword())){
                return dataOrdersBean.getKeyPassword();
            }
        }
        if (StringUtils.isNotEmpty(dataOrdersBean.getKeyId())){
            //TODO 从密钥表中获取密钥密码
            KeyContentVO keyContentNoAuth = secretsService.getKeyContentNoAuth(dataOrdersBean.getKeyId());
            return keyContentNoAuth.getKeyPassword();
        }
        return null;
    }

    /**
     * 校验登录用户是否有数据的操作权限
     * @param uuid  数据id
     * @return  数据对象
     * @throws MissingServletRequestParameterException    异常信息-主键参数必填
     * @throws NotFoundException    异常信息-未找到对象
     */
    private DataOrdersBean checkPermission(String uuid) throws MissingServletRequestParameterException, NotFoundException {
        if(StringUtils.isBlank(uuid)){
            throw new MissingServletRequestParameterException("主键字段uuid", "String");
        }
        SysUserBean loginUser = sysUserService.findLoginSysUser();
        if (loginUser == null) {
            throw new UserInfoInVaildException();
        }
        Optional<DataOrdersBean> optional = dataOrdersRepository.findById(uuid);
        //校验是否存在，如果不存在，直接返回成功
        if (!optional.isPresent()) {
            throw new NotFoundException("对象不存在");
        }
        DataOrdersBean bean = optional.get();
        //是否有查询权限
        if (!loginUser.getUuid().equalsIgnoreCase(bean.getCreatorId())) {
            throw new NotFoundException("对象不存在");
        }
        return bean;
    }

    /**
     * 校验登录用户是否有key_id对应密钥的使用权限
     * @param key_id  密钥表uuid
     * @return
     * @throws MissingServletRequestParameterException    异常信息-主键参数必填
     * @throws NotFoundException    异常信息-未找到对象
     */
    private SecretsBean checkKeyPermission(String key_id) throws MissingServletRequestParameterException, NotFoundException {
        if(StringUtils.isBlank(key_id)){
            throw new MissingServletRequestParameterException("主键字段uuid", "String");
        }
        SysUserBean loginUser = sysUserService.findLoginSysUser();
        if (loginUser == null) {
            throw new UserInfoInVaildException();
        }
        Optional<SecretsBean> optional = secretsRepository.findById(key_id);
        //校验是否存在，如果不存在，直接返回成功
        if (!optional.isPresent()) {
            throw new NotFoundException("对象不存在");
        }
        SecretsBean bean = optional.get();
        //是否有查询权限
        if (!loginUser.getUuid().equalsIgnoreCase(bean.getCreatorId())) {
            throw new NotFoundException("对象不存在");
        }
        return bean;
    }

    /**
     * 校验登录用户是否有key_id对应密钥的使用权限
     * @param key_id  密钥表uuid
     * @param algorithm 算法
     * @return
     */
    private Boolean checkKeyIdAlgorithm(String key_id,String algorithm) {
        if(StringUtils.isBlank(key_id)||StringUtils.isBlank(algorithm)){
            return false;
        }
        Optional<SecretsBean> optional = secretsRepository.findById(key_id);
        //校验是否存在，如果不存在，直接返回成功
        if (!optional.isPresent()) {
            return false;
        }
        SecretsBean bean = optional.get();
        //是否有查询权限
        if (!algorithm.equalsIgnoreCase(bean.getAlgorithm())) {
            return false;
        }
        return true;
    }

    /**
     * 系统自动删除计算完成的数据订单和数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAuto() {
        int rotateTime = Integer.parseInt(deleteCycle);
        //轮询数据表，校验计算完成和失败的数据的生成时间，超过预设周期自动删除
        String nowDate = DateUtil.getNowDate();
        List<DataOrdersBean> dataOrdersBeans = dataOrdersRepository.findAll();
        for (DataOrdersBean bean : dataOrdersBeans){
            if (KeyOrderStatus.Success.name().equalsIgnoreCase(bean.getStatus()) || KeyOrderStatus.Failed.name().equalsIgnoreCase(bean.getStatus())){
                try {
                    String createdTime = bean.getCreatedTime();
                    int difference = DateUtil.calculateTimeDifferenceBySimpleDateFormat(createdTime, nowDate);
                    if (difference>=rotateTime){
                        dataOrdersRepository.deleteById(bean.getUuid());
                        dataRepository.deleteById(bean.getDataId());
                    }
                } catch (ParseException e) {
                    log.error("校验数据删除时间周期失败: "+e.toString());
                }
            }
        }

    }
}
